package myapps.ttclient.asymmetric_encryption;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class RSA {

	public static byte[] rsaEncryptWithPublicKey(RSAKey publicKey, byte[] data) throws NoSuchAlgorithmException, 
		NoSuchProviderException, InvalidKeySpecException, NoSuchPaddingException, 
		InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		
		BigInteger modulus = publicKey.get_modulus();
		BigInteger exponent = publicKey.get_exponent();

		RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);

		KeyFactory fact = KeyFactory.getInstance("RSA");
		PublicKey pubKey = fact.generatePublic(keySpec);

		Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding");

		cipher.init(Cipher.ENCRYPT_MODE, pubKey);

		return cipher.doFinal(data);
	}

	public static byte[] rsaDecryptWithPrivateKey(RSAKey privateKey, byte[] cipherData) throws NoSuchAlgorithmException, 
		NoSuchProviderException, InvalidKeySpecException, 
		NoSuchPaddingException, InvalidKeyException, 
		IllegalBlockSizeException, BadPaddingException {

		BigInteger modulus = privateKey.get_modulus();
		BigInteger d = privateKey.get_exponent();

		RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, d);

		KeyFactory fact = KeyFactory.getInstance("RSA");
		PrivateKey priKey = fact.generatePrivate(keySpec);

		Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding");
		cipher.init(Cipher.DECRYPT_MODE, priKey);

		return cipher.doFinal(cipherData);
	}
}
